﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Settlements.TownMarketData
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using System.Collections.Generic;
using TaleWorlds.CampaignSystem.ComponentInterfaces;
using TaleWorlds.CampaignSystem.Extensions;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.Core;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Settlements
{
  public class TownMarketData : IMarketData
  {
    [SaveableField(1)]
    private Dictionary<ItemCategory, ItemData> _itemDict = new Dictionary<ItemCategory, ItemData>();
    [SaveableField(2)]
    private Town _town;

    internal static void AutoGeneratedStaticCollectObjectsTownMarketData(
      object o,
      List<object> collectedObjects)
    {
      ((TownMarketData) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      collectedObjects.Add((object) this._itemDict);
      collectedObjects.Add((object) this._town);
    }

    internal static object AutoGeneratedGetMemberValue_itemDict(object o)
    {
      return (object) ((TownMarketData) o)._itemDict;
    }

    internal static object AutoGeneratedGetMemberValue_town(object o)
    {
      return (object) ((TownMarketData) o)._town;
    }

    public TownMarketData(Town town) => this._town = town;

    public ItemData GetCategoryData(ItemCategory itemCategory)
    {
      ItemData categoryData;
      if (!this._itemDict.TryGetValue(itemCategory, out categoryData))
        categoryData = new ItemData();
      return categoryData;
    }

    public int GetItemCountOfCategory(ItemCategory itemCategory)
    {
      ItemData itemData;
      return !this._itemDict.TryGetValue(itemCategory, out itemData) ? 0 : itemData.InStore;
    }

    private void SetItemData(ItemCategory itemCategory, ItemData itemData)
    {
      this._itemDict[itemCategory] = itemData;
    }

    public void OnTownInventoryUpdated(ItemRosterElement item, int count)
    {
      if (item.EquipmentElement.Item == null)
        this.ClearStores();
      else
        this.AddNumberInStore(item.EquipmentElement.Item.GetItemCategory(), count, item.EquipmentElement.Item.Value);
    }

    public void AddDemand(ItemCategory itemCategory, float demandAmount)
    {
      SettlementEconomyModel consumptionModel = Campaign.Current.Models.SettlementConsumptionModel;
      this.SetItemData(itemCategory, this.GetCategoryData(itemCategory).AddDemand(consumptionModel.GetDemandChangeFromValue(demandAmount)));
    }

    public void AddSupply(ItemCategory itemCategory, float supplyAmount)
    {
      this.SetItemData(itemCategory, this.GetCategoryData(itemCategory).AddSupply(supplyAmount));
    }

    public void AddNumberInStore(ItemCategory itemCategory, int number, int value)
    {
      this.SetItemData(itemCategory, this.GetCategoryData(itemCategory).AddInStore(number, value));
    }

    public void SetSupplyDemand(ItemCategory itemCategory, float supply, float demand)
    {
      ItemData categoryData = this.GetCategoryData(itemCategory);
      this.SetItemData(itemCategory, new ItemData(supply, demand, categoryData.InStore, categoryData.InStoreValue));
    }

    public void SetDemand(ItemCategory itemCategory, float demand)
    {
      ItemData categoryData = this.GetCategoryData(itemCategory);
      this.SetItemData(itemCategory, new ItemData(categoryData.Supply, demand, categoryData.InStore, categoryData.InStoreValue));
    }

    public float GetDemand(ItemCategory itemCategory) => this.GetCategoryData(itemCategory).Demand;

    public float GetSupply(ItemCategory itemCategory) => this.GetCategoryData(itemCategory).Supply;

    public float GetPriceFactor(ItemCategory itemCategory)
    {
      ItemData categoryData = this.GetCategoryData(itemCategory);
      return Campaign.Current.Models.TradeItemPriceFactorModel.GetBasePriceFactor(itemCategory, (float) categoryData.InStoreValue, categoryData.Supply, categoryData.Demand, false, 0);
    }

    public int GetPrice(
      ItemObject item,
      MobileParty tradingParty = null,
      bool isSelling = false,
      PartyBase merchantParty = null)
    {
      return this.GetPrice(new EquipmentElement(item), tradingParty, isSelling);
    }

    public int GetPrice(
      EquipmentElement itemRosterElement,
      MobileParty tradingParty = null,
      bool isSelling = false,
      PartyBase merchantParty = null)
    {
      ItemData categoryData = this.GetCategoryData(itemRosterElement.Item.GetItemCategory());
      return Campaign.Current.Models.TradeItemPriceFactorModel.GetPrice(itemRosterElement, tradingParty, merchantParty, isSelling, (float) categoryData.InStoreValue, categoryData.Supply, categoryData.Demand);
    }

    public void UpdateStores()
    {
      this.ClearStores();
      ItemRoster itemRoster = this._town.Owner.ItemRoster;
      for (int index = 0; index < itemRoster.Count; ++index)
      {
        ItemRosterElement itemRosterElement = itemRoster[index];
        EquipmentElement equipmentElement = itemRosterElement.EquipmentElement;
        if (equipmentElement.Item.ItemCategory != null)
        {
          equipmentElement = itemRosterElement.EquipmentElement;
          ItemData categoryData = this.GetCategoryData(equipmentElement.Item.GetItemCategory());
          equipmentElement = itemRosterElement.EquipmentElement;
          ItemCategory itemCategory = equipmentElement.Item.GetItemCategory();
          ref ItemData local = ref categoryData;
          int amount = itemRosterElement.Amount;
          equipmentElement = itemRosterElement.EquipmentElement;
          int num = equipmentElement.Item.Value;
          ItemData itemData = local.AddInStore(amount, num);
          this.SetItemData(itemCategory, itemData);
        }
      }
    }

    private void ClearStores()
    {
      foreach (ItemCategory itemCategory in (List<ItemCategory>) ItemCategories.All)
      {
        ItemData categoryData = this.GetCategoryData(itemCategory);
        this.SetItemData(itemCategory, new ItemData(categoryData.Supply, categoryData.Demand, 0, 0));
      }
    }
  }
}
